package com.aotimes.yy.demo.act;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aotimes.yy.demo.exception.ExceptionUtils;
import com.aotimes.yy.demo.plugins.mongodb.MongoKit;
import com.jfinal.core.Controller;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.mongodb.DBCollection;

/**
 * @see 基础Act，封装了一些方法
 * @since 2016年1月21日
 * @category action
 * @author 杨阳
 */
public class BaseAct extends Controller {

	private static final Logger log = Logger.getLogger(BaseAct.class);

	/***************************************** 返回树数据方法 *******************************************/

	/**
	 * 获取机构树
	 * 
	 * @return json 字符串
	 */
	public String getGroupTree() {
		String sql = "select * from t_group";
		List<Map<String, Object>> treeList = new ArrayList<Map<String, Object>>();
		List<Record> list = Db.find(sql);
		for (int i = 0, length = list.size(); i < length; i++) {
			Record treeRecord = list.get(i);
			Map<String, Object> treeMap = treeRecord.getColumns();
			treeList.add(treeMap);
		}
		return JSONArray.toJSONString(treeList);
	}

	/***************************************** 返回树数据方法 *******************************************/

	/***************************************** 返回表格数据方法 *******************************************/
	/**
	 * @see 获取表格数据的公共方法
	 * @param sql
	 *            查询数据的sql语句
	 * @param tableName
	 *            表名或者是mongodbCollection的名称
	 * @return json数组
	 */
	public String getGridData(String sql, String tableName) {
		log.debug("---------------------get Table data---------------------");

		String offset = getPara("offset");
		String limit = getPara("limit");

		List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();

		Map<String, Object> map = new HashMap<>();

		String totalSql = getTotalSql(sql);

		long total = 0l;
		String dataBase = PropKit.get("usedatabase");

		if ("mysql".equals(dataBase) || "oracle".equals(dataBase)) {// 如果是mysql与oracle

			log.debug("SQL:[" + sql + "]");

			total = Db.queryLong(totalSql);
			map.put("total", total);// 返回所有条数

			long totalPage = (total - 1) / 10 + 1;
			map.put("page", totalPage);

			String litmitSql = getLimitSql(sql, offset, limit);
			List<Record> list = Db.find(litmitSql);
			for (int i = 0, length = list.size(); i < length; i++) {
				Record columnValues = list.get(i);
				Map<String, Object> m = columnValues.getColumns();
				rows.add(m);
			}
		} else if ("mongodb".equals(dataBase)) {// 如果是mongodb
			total = queryLongForMongoDb(tableName);
			map.put("total", total);// 返回所有条数

			long totalPage = (total - 1) / 10 + 1;
			map.put("page", totalPage);

			int startPage = Integer.parseInt(offset) / Integer.parseInt(limit) + 1;

			Page<Record> pageList = MongoKit.paginate(tableName, startPage, Integer.parseInt(limit));

			List<Record> list = pageList.getList();
			for (int i = 0, length = list.size(); i < length; i++) {
				Record columnValues = list.get(i);
				Map<String, Object> m = columnValues.getColumns();
				rows.add(m);
			}
		}

		map.put("rows", rows);
		String result = JSON.toJSONString(map);

		log.debug("data:[" + result + "]");
		log.debug("---------------------get Table data---------------------");
		return result;
	}

	/**
	 * 获得数据条数，试用于mongodb数据库
	 * 
	 * @param connectionName
	 * @return
	 */
	public long queryLongForMongoDb(String connectionName) {
		DBCollection dbc = MongoKit.getDBCollection(PropKit.get("mongodb.database"), connectionName);
		return dbc.count();
	}

	/**
	 * 获得查询全部条数的ＳＱＬ语句
	 * 
	 * @param sql
	 * @return
	 */
	public String getTotalSql(String sql) {
		StringBuffer sb = new StringBuffer();
		try {
			if (null == sql || "".equals(sql)) {
				throw new ExceptionUtils("没有传入SQL语句！");
			}

			sb.append(" select count(*) from ( ");
			sb.append(sql);
			sb.append(" ) tab");

		} catch (Exception e) {
			e.printStackTrace();
		}

		return sb.toString();
	}

	/**
	 * 获得可以分页的语句
	 * 
	 * @param sql
	 *            sql语句
	 * @param startRows
	 *            从第几条数据开始
	 * @param limit
	 *            每页显示几条
	 * @return
	 */
	public String getLimitSql(String sql, String startRows, String limit) {
		log.debug("传入ＳＱＬ:");
		log.debug(sql);

		StringBuffer sb = new StringBuffer();
		try {
			if (null == sql || "".equals(sql)) {
				throw new ExceptionUtils("没有传入SQL语句！");
			}

			sb.append(" select * from ( ");
			sb.append(sql);
			sb.append(" ) tab limit " + startRows + ", " + limit);

			log.debug("转换后ＳＱＬ:");
			log.debug(sb.toString());

		} catch (Exception e) {
			e.printStackTrace();
		}

		return sb.toString();
	}

	/***************************************** 返回表格数据方法 *******************************************/

	/***************************************** 数据库操作方法 *******************************************/

	/**
	 * 保存单一对象
	 * 
	 * @param tableName
	 *            数据库对应的表名
	 * @param rec
	 *            要保存的对象
	 */
	public boolean saveObj(String tableName, Record rec) {
		String dataBase = PropKit.get("usedatabase");
		boolean b = false;
		if ("mysql".equals(dataBase) || "oracle".equals(dataBase)) {// 如果是mysql与oracle
			b = Db.save(tableName, rec);
		} else if ("mongodb".equals(dataBase)) {// 如果是mongodb
			MongoKit.save(tableName, rec);
			b = true;
		}
		return b;
	}

	/**
	 * 根据ID删除某一对象
	 * 
	 * @param tableName
	 *            数据库对应的表名
	 * @param id
	 *            要删除对象的ID
	 * @return
	 */
	public boolean deleteObj(String tableName, String id) {
		String dataBase = PropKit.get("usedatabase");
		boolean b = false;
		if ("mysql".equals(dataBase) || "oracle".equals(dataBase)) {
			Db.deleteById(tableName, id);
		} else if ("mongodb".equals(dataBase)) {// 如果是mongodb
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("id", id);
			if (MongoKit.remove(tableName, param) > 0) {
				b = true;
			} else {
				b = false;
			}
		}
		return b;
	}

	/**
	 * 根据ＩＤ获得对象
	 * 
	 * @param tableName
	 *            数据库对应的表名
	 * @param id
	 *            对象ID
	 * @return
	 */
	public Record getObjById(String tableName, String id) {
		String dataBase = PropKit.get("usedatabase");
		Record record = new Record();
		if ("mysql".equals(dataBase) || "oracle".equals(dataBase)) {
			record = Db.findById(tableName, id);
		} else if ("mongodb".equals(dataBase)) {
			Map<String, Object> filter = new HashMap<String, Object>();
			filter.put("id", id);
			Page<Record> page = MongoKit.paginate(tableName, 1, 1, filter);
			List<Record> list = page.getList();
			record = list.get(0);
		}
		return record;
	}

	/**
	 * 更新对象
	 * 
	 * @param tableName
	 *            数据库对应的表名
	 * @param rec
	 *            要更新的对象
	 * @return
	 */
	public boolean updateObj(String tableName, Record rec) {
		String dataBase = PropKit.get("usedatabase");
		boolean b = false;
		if ("mysql".equals(dataBase) || "oracle".equals(dataBase)) {
			b = Db.update(tableName, rec);
		} else if ("mongodb".equals(dataBase)) {
			Map<String, Object> q = new HashMap<String, Object>();
			String id = rec.get("id");
			q.put("id", id);
			Map<String, Object> o = new HashMap<String, Object>();
			String[] columnes = rec.getColumnNames();
			for (int i = 0, length = columnes.length; i < length; i++) {
				String column = columnes[i];
				o.put(column, rec.get(column));
			}
			MongoKit.updateFirst(tableName, q, o);
			b = true;
		}
		return b;
	}

	/**
	 * 获得数据行数
	 * 
	 * @param sql
	 *            sql语句
	 * @return
	 */
	public long queryLong(String sql) {
		return Db.queryLong(sql);
	}

	/***************************************** 数据库操作方法 *******************************************/

	/***************************************** 操作json方法 *******************************************/
	public String successJson(String msg) {
		JSONObject json = new JSONObject();
		json.put("success", true);
		json.put("msg", msg);
		return json.toString();
	}

	public String errorJson(String msg) {
		JSONObject json = new JSONObject();
		json.put("success", false);
		json.put("msg", msg);
		return json.toString();
	}

	/***************************************** 操作json方法 *******************************************/

	/***************************************** 获取UUID方法 *******************************************/

	public String getUUID() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/***************************************** 获取UUID方法 *******************************************/
}
